home *** CD-ROM | disk | FTP | other *** search
- /* MHI DCR MAS-Player library */
-
- #include <clib/exec_protos.h>
- #include <clib/alib_protos.h>
- #include <clib/cia_protos.h>
- #include <clib/misc_protos.h>
- #include <clib/dos_protos.h>
-
- #include <exec/libraries.h>
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <exec/lists.h>
- #include <exec/interrupts.h>
- #include <hardware/intbits.h>
- #include <hardware/cia.h>
- #include <resources/cia.h>
- #include <resources/misc.h>
-
- #include "mhi.h"
-
- #pragma libbase MHIBase
-
-
- extern void dcr_pro_int();
- extern void SetupParPort();
- extern void SetVolume(register __d0 ULONG vol);
- extern void SetPrefactor(register __d0 UWORD prefac);
- extern void SetBass(register __d0 UWORD bass);
- extern void SetTreble(register __d0 UWORD treb);
-
- /* volume
- * first is loudest
- * 21 total
- */
-
- ULONG voltab[21] =
- {0x80000,0x8DEB8,0x9A537,0xA5621,0xAF3CD,0xB8053,0xBFD92,0xC6D31,
- 0xCD0AD,0xD2958,0xD785E,0xDBECC,0xDFD91,0xE3583,0xE675F,0xE93CF,
- 0xEBB6A,0xEDEB6,0xEFE2C,0xF1A36,0xFFFFA};
-
- /* prefactor
- * first is quietest
- * 16 total
- */
-
- UWORD preftab[16] =
- {0x8000,0x8E00,0x9A40,0xA580,0xAF40,0xB800,0xBFC0,0xC6C0,
- 0xCD00,0xD25C,0xD780,0xDC00,0xDFC0,0xE340,0xE680,0xE940};
-
- /* bass
- * 0x0000 (15) is normal
- * 31 total
- */
-
- UWORD basstab[31] =
- {0x9E40,0xA280,0xA740,0xAC40,0xB180,0xB740,0xBD40,0xC3C0,
- 0xCA40,0xD180,0xD8C0,0xE040,0xE800,0xEFC0,0xF7C0,0x0000,
- 0x0800,0x1000,0x17C0,0x1F80,0x2700,0x2E40,0x3580,0x3C00,
- 0x4280,0x4880,0x4E40,0x5380,0x5880,0x5D40,0x6180};
-
- /* treble
- * 0x0000 (15) is normal
- * 31 total
- */
-
- UWORD trebtab[31] =
- {0xB2C0,0xBB40,0xC180,0xC6C0,0xCBC0,0xD040,0xD500,0xD980,
- 0xDE00,0xE280,0xE7E0,0xEC00,0xF0C0,0xF5C0,0xFAC0,0x0000,
- 0x0540,0x0AC0,0x1040,0x1600,0x1C00,0x2200,0x2840,0x2EC0,
- 0x3540,0x3C00,0x42C0,0x49C0,0x5180,0x5840,0x5F80};
-
- STRPTR DriverName = "MAS Player Pro";
- STRPTR DriverVersion = "$VER: 1.2 Final (02/04/01)";
- STRPTR DriverAuthor = "Paul Qureshi";
-
- struct MPHandle
- {
- APTR data; /* current buffer node */
- APTR endnode; /* node at the end of the list */
- struct Task *task; /* task that wants signals */
- ULONG mhisignal; /* signal mask to use */
- UBYTE status; /* player status flags */
- UBYTE oldstatus; /* last status */
-
- UBYTE volume;
- UBYTE panning;
- UBYTE mixing;
- UBYTE prefactor;
- UBYTE bass;
- UBYTE treble;
- UBYTE mid;
- };
-
- struct MPBufferNode
- {
- struct MinNode my_MinNode;
- APTR buffer;
- APTR pos;
- ULONG bytesleft;
- };
-
- /* Prototypes */
-
- APTR MHIAllocDecoder (register __a0 struct Task *task, register __d0 ULONG mhisignal);
- VOID StartTimer (struct freetimer *ft);
- BOOL FindFreeTimer (struct freetimer *ft, int preferA);
- BOOL TryTimer (struct freetimer *ft);
- VOID MHIFreeDecoder (register __a3 APTR handle);
- BOOL MHIQueueBuffer (register __a3 MPHandle *handle, register __a0 APTR buffer, register __d0 ULONG size);
- APTR MHIGetEmpty (register __a3 MPHandle *handle);
- UBYTE MHIGetStatus (register __a3 MPHandle *handle);
- VOID MHIPlay (register __a3 MPHandle *handle);
- VOID MHIStop (register __a3 MPHandle *handle);
- VOID MHIPause (register __a3 MPHandle *handle);
- ULONG MHIQuery (register __d1 ULONG query);
- VOID MHISetParam (register __a3 MPHandle *handle, register __d0 UWORD param, register __d1 ULONG value);
-
- struct MinList BufList;
-
- BOOL mhiallocated;
-
- UBYTE *owner = NULL;
- struct Library *MiscBase = NULL;
-
- /*
- * CIA stuff
- *
- */
-
- #define HICOUNT 0x0A
- #define LOCOUNT 0x00
-
- #define STOPA_AND CIACRAF_TODIN | CIACRAF_PBON | CIACRAF_OUTMODE | CIACRAF_SPMODE
- #define STOPB_AND CIACRBF_ALARM | CIACRBF_PBON | CIACRBF_OUTMODE
-
- #define STARTA_OR CIACRAF_START
- #define STARTB_OR CIACRBF_START
-
- /*
- * Structure which will be used to hold all relevant information about
- * the cia timer we manage to allocate.
- *
- */
-
- struct freetimer
- {
- struct Library *ciabase; /* CIA Library Base */
- ULONG timerbit; /* timer bit allocated */
- struct CIA *cia; /* ptr to hardware */
- UBYTE *ciacr; /* ptr to control register */
- UBYTE *cialo; /* ptr to low byte of timer */
- UBYTE *ciahi; /* ptr to high byte of timer */
- struct Interrupt timerint; /* Interrupt structure */
- UBYTE stopmask; /* Stop/set-up timer */
- UBYTE startmask; /* Start timer */
- };
-
- struct CIA *ciaa = (struct CIA *)0xbfe001;
- struct CIA *ciab = (struct CIA *)0xbfd000;
-
- struct freetimer ft;
-
- /* --------------------------------------------------------------------- */
- /* Start of code */
- /* --------------------------------------------------------------------- */
-
- APTR MHIAllocDecoder(register __a0 struct Task *task, register __d0 ULONG mhisignal)
- /* Allocate MHI. Open all needed resources etc, and be prepared
- to output.
-
- *task is the task that wants signals
- mhisignal is the signal mask to use
- */
- {
- struct MPHandle *handle;
-
- if (!mhiallocated)
- if ( handle = AllocMem(sizeof(MPHandle), MEMF_CLEAR) )
- {
- handle->task = task;
- handle->mhisignal = mhisignal;
- handle->status = MHIF_STOPPED;
-
- handle->volume = 100;
- handle->panning = 50;
- handle->mixing = 50;
- handle->prefactor = 50;
- handle->bass = 50;
- handle->treble = 50;
- handle->mid = 50;
-
- SetVolume(voltab[0]);
- SetPrefactor(preftab[0]);
- SetBass(basstab[15]);
- SetTreble(trebtab[15]);
-
- if ( MiscBase = (struct Library *)OpenResource(MISCNAME) )
- {
- if ( ((owner = AllocMiscResource(MR_PARALLELPORT, "MHI")) == NULL)
- && ((owner = AllocMiscResource(MR_PARALLELBITS, "MHI")) == NULL) )
- {
-
- SetupParPort(); // set par port bits
-
- ft.timerint.is_Node.ln_Type = NT_INTERRUPT;
- ft.timerint.is_Node.ln_Pri = 0;
- ft.timerint.is_Node.ln_Name = "MHI_MAS_Player_Pro";
- ft.timerint.is_Data = handle;
- ft.timerint.is_Code = dcr_pro_int;
-
- if (FindFreeTimer(&ft,TRUE))
- {
- StartTimer(&ft);
-
- /* setup main list */
- BufList.mlh_Head = (struct MinNode *) &BufList.mlh_Tail;
- BufList.mlh_Tail = 0;
- BufList.mlh_TailPred = (struct MinNode *) &BufList.mlh_Head;
- mhiallocated = TRUE;
- return handle;
- }
- else
- return 0L;
- }
- else
- return 0L;
- }
- else
- return 0L;
- }
- else
- return 0L;
- else
- return 0L;
- }
-
- VOID MHIFreeDecoder(register __a3 APTR handle)
- /* Free MHI and all resources
- */
- {
- APTR killednode;
-
- if (handle)
- {
- RemICRVector(ft.ciabase,ft.timerbit,&ft.timerint);
-
- FreeMem(handle, sizeof(MPHandle));
-
- FreeMiscResource(MR_PARALLELPORT);
- FreeMiscResource(MR_PARALLELBITS);
-
- /* free buffer list */
- while ( killednode = RemHead((struct List *)&BufList) )
- FreeMem(killednode, sizeof(struct MPBufferNode));
-
- mhiallocated = FALSE;
- }
- }
-
- BOOL MHIQueueBuffer(register __a3 MPHandle *handle, register __a0 APTR buffer, register __d0 ULONG size)
- /* Add this buffer to the queue
- */
- {
- struct MPBufferNode *newnode;
-
- if (!( newnode = AllocMem(sizeof(MPBufferNode), MEMF_CLEAR) ))
- return FALSE;
- else
- {
- newnode->buffer = buffer;
- newnode->pos = buffer;
- newnode->bytesleft = size;
- AddTail((struct List *)&BufList,(struct Node *)newnode);
- handle->endnode = newnode;
-
- if (handle->data == 0)
- handle->data = newnode;
-
- return TRUE;
- }
- }
-
- APTR MHIGetEmpty(register __a3 MPHandle *handle)
- /* Find the next empty buffer node and return the buffers address
- */
- {
- struct MPBufferNode *mynode;
- APTR temp = 0;
-
- mynode = (MPBufferNode *)BufList.mlh_Head;
-
- for (mynode = (MPBufferNode *)BufList.mlh_Head ; mynode->my_MinNode.mln_Succ ; mynode = (MPBufferNode *)mynode->my_MinNode.mln_Succ)
- if (mynode->bytesleft == 0)
- temp = mynode;
-
- mynode = temp;
-
- if ((APTR)mynode != &BufList && mynode != 0)
- {
- Remove((struct Node *)mynode);
- temp = mynode->buffer;
- FreeMem(mynode, sizeof(struct MPBufferNode));
- return temp;
- }
- else
- return 0L;
- }
-
- UBYTE MHIGetStatus(register __a3 MPHandle *handle)
- /* Get the MHI players status flags
- */
- {
- return handle->status;
- }
-
- VOID MHIPlay(register __a3 MPHandle *handle)
- /* Set the player to play mode
- */
- {
- handle->status = MHIF_PLAYING;
- }
-
- VOID MHIStop(register __a3 MPHandle *handle)
- /* Stop the player and free all buffers
- */
- {
- APTR killednode;
-
- handle->status = MHIF_STOPPED;
- handle->data = 0;
- /* free buffer list */
- while ( killednode = RemHead((struct List *)&BufList) )
- FreeMem(killednode, sizeof(struct MPBufferNode));
- }
-
- VOID MHIPause(register __a3 MPHandle *handle)
- /* Pause the player
- */
- {
- if (handle->status == MHIF_PAUSED) /* Unpause */
- handle->status = MHIF_PLAYING;
- else
- if (handle->status == MHIF_PLAYING) /* Pause */
- handle->status = MHIF_PAUSED;
- }
-
- ULONG MHIQuery(register __d1 ULONG query)
- /* Respond to a feature query from an application
- */
- {
- switch (query)
- {
- case MHIQ_MPEG1: case MHIQ_MPEG2: case MHIQ_MPEG25:
- return MHIF_SUPPORTED;
- break;
-
- case MHIQ_MPEG4:
- return MHIF_UNSUPPORTED;
- break;
-
- case MHIQ_LAYER1:
- return MHIF_UNSUPPORTED;
- break;
-
- case MHIQ_LAYER2: case MHIQ_LAYER3:
- return MHIF_SUPPORTED;
- break;
-
- case MHIQ_VARIABLE_BITRATE:
- return MHIF_SUPPORTED;
- break;
-
- case MHIQ_JOINT_STERIO:
- return MHIF_SUPPORTED;
- break;
-
- case MHIQ_BASS_CONTROL: case MHIQ_TREBLE_CONTROL: case MHIQ_MID_CONTROL:
- return MHIF_UNSUPPORTED;
- break;
-
- case MHIQ_VOLUME_CONTROL: case MHIQ_PANNING_CONTROL: case MHIQ_CROSSMIXING:
- return MHIF_UNSUPPORTED;
- break;
-
- case MHIQ_IS_HARDWARE:
- return MHIF_TRUE;
- break;
-
- case MHIQ_IS_68K: case MHIQ_IS_PPC:
- return MHIF_FALSE;
- break;
-
- case MHIQ_DECODER_NAME:
- return (ULONG) DriverName;
- break;
-
- case MHIQ_DECODER_VERSION:
- return (ULONG) DriverVersion;
- break;
-
- case MHIQ_AUTHOR:
- return (ULONG) DriverAuthor;
- break;
-
- default:
- return MHIF_UNSUPPORTED;
- break;
- }
- }
-
- VOID MHISetParam(register __a3 MPHandle *handle, register __d0 UWORD param, register __d1 ULONG value)
- /* Set decoder paramiter.
- */
- {
- UBYTE calc;
-
- switch (param)
- {
- case MHIP_VOLUME:
-
- if (value != handle->volume)
- {
- handle->oldstatus = handle->status;
- handle->status = MHIF_PAUSED;
-
- handle->volume = value;
- calc = (float)(100 - value) * 0.2;
- if (calc > 20)
- calc = 20;
- if (calc < 0)
- calc = 0;
- SetVolume(voltab[calc]);
-
- handle->status = handle->oldstatus;
- }
-
- break;
-
- case MHIP_PANNING:
-
- if (value != handle->panning)
- {
- handle->panning = value;
- }
-
- break;
-
- case MHIP_CROSSMIXING:
-
- if (value != handle->mixing)
- {
- handle->mixing = value;
- }
-
- break;
-
- case MHIP_PREFACTOR:
-
- if (value != handle->prefactor)
- {
- handle->prefactor = value;
- if (value > 50)
- {
- value -= 50; // only prefactors above 50
- if (value < 0) // are used by the MAS3507
- value = 0;
- calc = (float)value * .3;
- if (calc > 15)
- calc = 15;
- if (calc < 0)
- calc = 0;
- }
- else
- {
- calc=0;
- }
- SetPrefactor(preftab[calc]);
- }
-
- break;
-
- case MHIP_BASS:
-
- if (value != handle->bass)
- {
- handle->bass = value;
- calc = (float)value * 0.3;
- if (calc > 30)
- calc = 30;
- if (calc < 0)
- calc = 0;
- SetBass(basstab[calc]);
- }
-
- break;
-
- case MHIP_TREBLE:
-
- if (value != handle->treble)
- {
- handle->treble = value;
- calc = (float)value * 0.3;
- if (calc > 30)
- calc = 30;
- if (calc < 0)
- calc = 0;
- SetTreble(trebtab[calc]);
- }
-
- break;
-
- case MHIP_MID:
-
- if (value != handle->mid)
- {
- handle->mid = value;
- // SetMid(mid);
- }
-
- break;
-
- }
-
- }
-
- void StartTimer(struct freetimer *ft)
- {
- register struct CIA *cia;
-
- cia = ft->cia;
-
- /* Note that there are differences between control register A,
- * and B on each CIA (e.g., the TOD alarm bit, and INMODE bits.
- */
-
- if (ft->timerbit == CIAICRB_TA)
- {
- ft->ciacr = &cia->ciacra; /* control register A */
- ft->cialo = &cia->ciatalo; /* low byte counter */
- ft->ciahi = &cia->ciatahi; /* high byte counter */
-
- ft->stopmask = STOPA_AND; /* set-up mask values */
- ft->startmask = STARTA_OR;
- }
- else
- {
- ft->ciacr = &cia->ciacrb; /* control register B */
- ft->cialo = &cia->ciatblo; /* low byte counter */
- ft->ciahi = &cia->ciatbhi; /* high byte counter */
-
- ft->stopmask = STOPB_AND; /* set-up mask values */
- ft->startmask = STARTB_OR;
- }
-
- Disable();
- *ft->ciacr &= ft->stopmask;
- Enable();
-
- /* Clear signal bit - interrupt will signal us later */
- /* SetSignal(0L,1L<<ed->signal);
- */
-
- *ft->cialo = LOCOUNT;
- *ft->ciahi = HICOUNT;
-
- /* Turn on start bit - same bit for both A, and B control regs */
-
- Disable();
- *ft->ciacr |= ft->startmask;
- Enable();
- }
-
-
-
- BOOL FindFreeTimer(struct freetimer *ft, int preferA)
- {
- //struct CIABase *ciaabase, *ciabbase;
- struct Library *ciaabase, *ciabbase;
-
- ciaabase = OpenResource(CIAANAME);
- ciabbase = OpenResource(CIABNAME);
-
- if (preferA)
- {
- ft->ciabase = ciaabase; /* library address */
- ft->cia = ciaa; /* hardware address */
- }
- else
- {
- ft->ciabase = ciabbase; /* library address */
- ft->cia = ciab; /* hardware address */
- }
-
- if (TryTimer(ft))
- return(TRUE);
-
- if (!(preferA))
- {
- ft->ciabase = ciaabase; /* library address */
- ft->cia = ciaa; /* hardware address */
- }
- else
- {
- ft->ciabase = ciabbase; /* library address */
- ft->cia = ciab; /* hardware address */
- }
-
- if (TryTimer(ft))
- return(TRUE);
-
- return(FALSE);
-
- }
-
-
-
- BOOL TryTimer(struct freetimer *ft)
- {
-
- if (!(AddICRVector(ft->ciabase,CIAICRB_TA,&ft->timerint)))
- {
- ft->timerbit = CIAICRB_TA;
- return(TRUE);
- }
-
- if (!(AddICRVector(ft->ciabase,CIAICRB_TB,&ft->timerint)))
- {
- ft->timerbit = CIAICRB_TB;
- return(TRUE);
- }
-
- return(FALSE);
- }